﻿using System;
using System.Collections.Generic;
using System.Linq;
using BankCreditPortfolio.DAL.Entities;

namespace BankCreditPortfolio.DAL.Services
{
    public class AgreementService : DataService<AgreementPersistence>
    {
        public Agreement GetByOrderId(int orderId)
        {
            var filteredQuery = this.CreateQuery().Where(x => x.Order.OrderId == orderId);
            return filteredQuery.Count() > 0 ? filteredQuery.Single() : null;
        }
        
        public IQueryable<Agreement> GetAllByEmail(string email)
        {
            var filteredQuery = this.CreateQuery().Where(x => x.Order.Client.Account.Email == email &&
                x.Order.OrderStatus.Status != "Repayed");
            return filteredQuery.Count() > 0 ? filteredQuery : null;
        }

        public IQueryable<Agreement> GetActive()
        {
            var filteredQuery =
                this.CreateQuery().Where(x => x.Order.OrderStatus.Status != "Repayed");
            return filteredQuery.Count() > 0 ? filteredQuery : null;
        }

        public IQueryable<Agreement> GetAccepted()
        {
            var filteredQuery =
                this.CreateQuery().Where(x => x.Order.OrderStatus.OrderStatusId == 5).OrderByDescending(
                    x => x.Credit.DeliveryDate);
            return filteredQuery.Count() > 0 ? filteredQuery : null;
        }

        public decimal GetAmountByPeriod(DateTime start, DateTime stop )
        {
            var filteredQuery =
                this.CreateQuery().Where(x => x.Order.OrderStatus.OrderStatusId == 5 && x.Credit.DeliveryDate >= start && x.Credit.DeliveryDate < stop);
            decimal summ = 0;
            if (filteredQuery.Count() > 0)
            {
                foreach (var agreement in filteredQuery)
                {
                    switch (agreement.Order.Currency.Title)
                    {
                        case "BYR":
                            summ += agreement.Order.Amount/8700;
                            break;
                        case "EURO":
                            summ += agreement.Order.Amount*(decimal) 1.56;
                            break;
                        case "RUR":
                            summ += agreement.Order.Amount/30;
                            break;
                        default:
                            summ += agreement.Order.Amount;
                            break;
                    }
                }
            }
            return summ;
        }
        
        private Tariff GetTariffObject(TariffPersistence obj)
        {
            var result = new Tariff
            {
                TariffId = obj.TariffId,
                CreditPercent = obj.CreditPercent,
                Currency = obj.Currency,
                Description = obj.Description,
                FirstPayment = obj.FirstPayment,
                Max = obj.Max,
                Min = obj.Min,
                NumberOfGuarantors = obj.NumberOfGuarantors,
                OtherPayments = obj.OtherPayments,
                Time = obj.Time,
                Title = obj.Title,
                Fine = obj.Fine,
                EarlyRepaymentFine = obj.EarlyRepaymentFine,
                Used = obj.Used
            };
            return result;
        }

        private OrderInfo GetOrderInfoObject(OrderInfoPersistence obj)
        {
            var res = new OrderInfo
            {
                Currency = obj.Currency,
                Documents = obj.Documents,
                Gains = obj.Gains,
                //Guarantor = obj.Guarantor,
                OrderId = obj.OrderId,
                OrderStatus = obj.OrderStatus,
                Tariff = GetTariffObject(obj.Tariff),
                Client = obj.Client,
                Amount = obj.Amount,
                GainsCurrency = obj.GainsCurrency
            };
            return res;
        }

        private Agreement GetAgreementObject(AgreementPersistence obj)
        {
            var res = new Agreement
                          {
                              AgreementId = obj.AgreementId,
                              Banker = obj.Banker,
                              //Client = obj.Client,
                              Credit = obj.Credit,
                              Order = GetOrderInfoObject(obj.Order)
                          };
            return res;
        }

        new public Agreement Find(int id)
        {
            return GetAgreementObject(base.Find(id));
        }

        new public IEnumerable<Agreement> GetAll()
        {
            return base.GetAll().Select(GetAgreementObject).ToList();
        }

        public override bool Save(ref AgreementPersistence entity)
        {
            var obj = GetAgreementObject(entity);
            var result = this.Save(ref obj);
            entity.AgreementId = obj.AgreementId;
            return result;
        }

        public bool Save(ref Agreement entity)
        {
            var tmp = base.Find(entity.AgreementId);
            var obj = new AgreementPersistence
                          {
                              Banker = entity.Banker,
                              Credit = entity.Credit,
                              AgreementId = entity.AgreementId,
                              //Client = entity.Client,
                              Order = new OrderInfoPersistence
                                          {
                                              Currency = entity.Order.Currency,
                                              Documents = entity.Order.Documents,
                                              Gains = entity.Order.Gains,
                                              //Guarantor = entity.Order.Guarantor,
                                              OrderId = entity.Order.OrderId,
                                              OrderStatus = entity.Order.OrderStatus,
                                              Client = entity.Order.Client,
                                              Amount = entity.Order.Amount,
                                              GainsCurrency = entity.Order.GainsCurrency,
                                              Tariff = new TariffPersistence
                                                           {
                                                               CreditPercent = entity.Order.Tariff.CreditPercent,
                                                               Currency = entity.Order.Tariff.Currency,
                                                               Description = entity.Order.Tariff.Description,
                                                               FirstPayment = entity.Order.Tariff.FirstPayment,
                                                               Max = entity.Order.Tariff.Max,
                                                               Min = entity.Order.Tariff.Min,
                                                               NumberOfGuarantors =
                                                                   entity.Order.Tariff.NumberOfGuarantors,
                                                               OtherPayments = entity.Order.Tariff.OtherPayments,
                                                               Time = entity.Order.Tariff.Time,
                                                               Title = entity.Order.Tariff.Title,
                                                               Fine = entity.Order.Tariff.Fine,
                                                               TariffId = entity.Order.Tariff.TariffId,
                                                               EarlyRepaymentFine = entity.Order.Tariff.EarlyRepaymentFine,
                                                               Used = entity.Order.Tariff.Used
                                                           }
                                          }
                          };
            if(tmp == null)
                tmp= new AgreementPersistence();
            tmp.Banker = obj.Banker;
            tmp.Credit = obj.Credit;
            tmp.Order = obj.Order;
            var res = base.Save(ref tmp);
            entity.AgreementId = obj.AgreementId;
            return res;
        }

        new public IQueryable<Agreement> CreateQuery()
        {
            var tmpCollection1 = base.CreateQuery();
            var tmpCollection = new List<Agreement>();
            foreach (var clientPersistence in tmpCollection1)
            {
                tmpCollection.Add(GetAgreementObject(clientPersistence));
            }
            return tmpCollection.AsQueryable();
        }
    }
}
